<template>
  <view class="content">
    <!-- 保留 type="2d"，并添加 ref 用于获取节点 -->
<!--    @touchstart="bindTouchstart"-->
<!--    @touchmove="bindTouchmove"-->
<!--    @touchend="bindTouchend"-->

    <div class="left">
      <uni-section title="本地图片"  type="line" padding>
        <uni-tag text="本地图片" type="primary" @click="chooseImg()">本地图片</uni-tag>
      </uni-section>
      <uni-section title="网络图片"  type="line" padding>
        <uni-easyinput v-model="imgUrl" placeholder="请输入图片地址"  confirmType="完成" suffix-icon="cloud-upload" @iconClick="bindImg" />
      </uni-section>
    </div>
    <canvas ref="canvasRef"
            style="width: 400px; height: 500px; min-width: 400px; min-height: 500px; border: 1px solid #7a7272; margin: 0 auto;" type="2d"
            id="firstCanvas"
            @mousedown="bindTouchstart"
            @mousemove="bindTouchmove"
            @mouseup="bindTouchend"
    />
    <div class="right">
      <uni-section title="文字"  type="line" padding>
        <uni-easyinput styles="width: 300px;" v-model="text"
                       placeholder="请输入文字内容" type="textarea"
                       autoHeight confirmType="完成"
                       suffix-icon="cloud-upload"
                       @input="bindChangeText"
                       @iconClick="bindText" />
        <view class="example-body" style="display: grid; grid-template-columns: repeat(4, 1fr); gap: 20px; margin: 20rpx 0;">
          <view class="tag-view" >
            <uni-tag text="横向排列" type="primary" @click="updateText('horizontal', 'horizontal')" />
          </view>
          <view class="tag-view">
            <uni-tag text="竖向排列" type="primary" @click="updateText('vertical', 'vertical')"/>
          </view>
          <view class="tag-view">
            <uni-tag text="文字描边"  type="primary" @click="updateText('lineWidth', '2')"/>
          </view>
          <view class="tag-view">
            <uni-tag text="加粗"  type="primary" @click="updateText('fontWeight', 'bold')"/>
          </view>
          <view class="tag-view">
            <uni-tag text="斜体"  type="primary" @click="updateText('fontStyle', 'italic')"/>
          </view>
          <view class="tag-view">
            <uni-tag text="下划线"  type="primary" @click="updateText('underline', 'underline')"/>
          </view>
          <view class="tag-view">
            <uni-tag text="textAlign"  type="primary" @click="updateText('', 'x')"/>
          </view>
          <view class="tag-view">
            <uni-tag text="textBaseline"  type="primary" @click="updateText('', 'x')"/>
          </view>
          <view class="tag-view">
            <uni-tag text="textColor"  type="primary" @click="updateText('fillStyle', `#${Math.floor(Math.random()*16777215).toString(16).padStart(6, '0')}`)"/>
          </view>
        </view>
      </uni-section>
    </div>
  </view>

  <div class="">
    <uni-section title="图层"  type="line" padding>

      <template v-for="img in images">
        <image mode="aspectFit" :src="img" @click="bindPreview()"></image>
      </template>
    </uni-section>
  </div>
  <div class="footer" v-if="false">
    <uni-section title="方向"  type="line" padding>
      <view class="example-body" style="display: flex; gap: 20px;">
        <view class="tag-view">
          <uni-tag text="X" type="primary" @click="changeDirection('x')" />
        </view>
        <view class="tag-view">
          <uni-tag text="y" type="primary" @click="changeDirection('y')"/>
        </view>
        <view class="tag-view">
          <uni-tag text="复制"  type="primary" @click="copy('copy')"/>
        </view>
      </view>
    </uni-section>
    <uni-section title="层级"  type="line" padding>
      <view class="example-body" style="display: flex; gap: 20px;">
        <view class="tag-view">
          <uni-tag text="顶层" type="primary" @click="changeZIndex('top')" />
        </view>
        <view class="tag-view">
          <uni-tag text="上一层" type="primary" @click="changeZIndex('up')"/>
        </view>
        <view class="tag-view">
          <uni-tag text="下一层"  type="primary" @click="changeZIndex('down')"/>
        </view>
        <view class="tag-view">
          <uni-tag text="底层" type="primary" @click="changeZIndex('bottom')" />
        </view>
      </view>
    </uni-section>
    <uni-section title="历史"  type="line" padding>
      <view class="example-body" style="display: flex; gap: 20px;">
        <view class="tag-view">
          <uni-tag text="上一步" type="primary" @click="changeHistory('pre')" />
        </view>
        <view class="tag-view">
          <uni-tag text="下一部" type="primary" @click="changeHistory('next')"/>
        </view>
      </view>
    </uni-section>
  </div>

</template>

<script setup lang="ts">
import {
  ref,
  onMounted, shallowRef
} from 'vue';
import {ImageNode, ImageNodeBox, Placard, PlacardTools, RotateControl, ScaleControl, TextNodeBox, TextNode} from "../../../../canvas-test/dist/index.js";
import {DeleteControl, ReplaceControl} from "../../../../canvas-test";

// 创建一个 ref 来引用 canvas 元素
const canvasRef = ref(null);
let placard: Placard;

onMounted(() => {
  // 使用新版 Canvas API
  const query = uni.createSelectorQuery();
  query
      .select('#firstCanvas')
      .fields({
        node: true,
        size: true
      })
      .exec((res) => {
        if (res[0]) {
          const canvas = res[0].node;
          const ctx = canvas.getContext('2d');
          // 处理高DPI屏幕，使绘制更清晰
          const dpr = uni.getSystemInfoSync().pixelRatio;
          canvas.width = res[0].width * dpr;
          canvas.height = res[0].height * dpr;
          ctx.scale(dpr, dpr);

          placard = new Placard({
            canvas: canvas,
            canvasWidth: 400,
            canvasHeight: 500,
            backgroundColor: "#000000",
          })
          const renderReact = placard.getRenderReact();
          const scaleControl = new ScaleControl(renderReact);
          const rotateControl = new RotateControl(renderReact);
          const deleteControl = new DeleteControl(renderReact, {event: {
              down: (point, node) => {
                console.log('onDelete', {node, point})
                uni.showToast({
                  title: `你点击了《 ${node.id} 》节点的删除按钮`,
                  icon: 'none',
                  duration: 2000
                })
                placard.removeNode(node.id)
                placard.renderDraw()
              }
            }});
          const replaceControl = new ReplaceControl(renderReact,
              {event: {
                  down: (point, node) => {
                    console.log('replace', {node, point})
                    uni.showToast({
                      title: `你点击了《 ${node.id} 》节点的替换按钮`,
                      icon: 'none',
                      duration: 2000
                    })
                    chooseImg('replace')
                  }
                }});

          placard.loadControl([scaleControl, rotateControl, deleteControl, replaceControl]);
          window._placard = placard;
        }
      });
});

const chooseImg = (type = '') => {
  uni.chooseImage({
    count: 1,
    sizeType: ['original', 'compressed'],
    sourceType: ['album', 'camera'],
    success: async (res) => {
      const tempFilePath = res.tempFilePaths[0];
      const base64 = await PlacardTools.imageToBase64(tempFilePath)
      const img = new Image();
      img.src = `${base64}`;
      img.onload = () => {

        const imageNode = new ImageNode({
          data: img,
          width: 200,
          height: 200,
          url: tempFilePath,
          scale: 1,
          base64
        })
        if(type === 'replace') {
          const selectNode = placard!.canvasEvent.getSelectNode();
          if(selectNode && selectNode.getType() === 'img') {
            selectNode.replaceImage(imageNode)
            selectNode.drawCache();
          }
        }else {
          const imageNodeBox = new ImageNodeBox(imageNode, placard!.getRenderReact())
          imageNodeBox.setMode('aspectFit', {maxWidth: 200, maxHeight: 200})
          imageNodeBox.drawCache();
          placard.addNode(imageNodeBox)
        }

        placard.renderDraw()
      }

    }
  })
}

let isStart = false;
const bindTouchstart = (e: any) => {
  // console.log('bindTouchstart', e)
  isStart = true;
  placard!.canvasEvent.down(e)

  const selectNode = placard!.canvasEvent.getSelectNode();
  if(selectNode && selectNode.getType() === 'text') {
    text.value = selectNode._textNode.text;
  }
}
const bindTouchmove = (e: any) => {
  isStart && placard!.canvasEvent.move(e)
}
const bindTouchend = (e: any) => {
  // console.log('bindTouchend', e)
  placard!.canvasEvent.up(e);
  isStart = false;
}

const imgUrl = ref('https://www.baidu.com/img/flexible/logo/pc/result.png')
const bindImg = (e) => {
  console.log('bindImg', imgUrl.value)
  if(imgUrl.value.indexOf('http') !== 0) {
    uni.showLoading({
      title: '非法图片链接',
      mask: true
    })
    return;
  }
  ImageNode.createImageData(imgUrl.value).then( async (img) => {
    console.log('createImageData', img)
    const base64Data = await PlacardTools.imageToBase64(img.src);
    const imageNode = new ImageNode({
      data: img,
      width: img.width,
      height: img.height,
      url: imgUrl.value,
      scale: 1,
      base64: base64Data
    })

    const imageNodeBox = new ImageNodeBox(imageNode, placard!.getRenderReact())
    imageNodeBox.setMode('aspectFit', {maxWidth: 200, maxHeight: 200})
    imageNodeBox.isSelected = true;
    imageNodeBox.drawCache();
    placard.addNode(imageNodeBox)
    placard.renderDraw()
  });
}


const changeZIndex = (type: 'top' | 'up' | 'down' | 'bottom') => {
  const selectNodeBox = placard.canvasEvent.getSelectNode();
  if (!selectNodeBox) return;
  placard.reorderZIndexNode(selectNodeBox, type);
  placard.renderDraw();
}

const changeDirection = (type: 'x' | 'y') => {
  const selectNodeBox = placard.canvasEvent.getSelectNode();
  if (!selectNodeBox) return;
  selectNodeBox.flip(type);
  selectNodeBox.drawCache();
  placard.renderDraw();
}
const copy = async (type: 'copy') => {
  const copyNode = placard.canvasEvent.getSelectNode()?.copy();
  if (!copyNode) {
    uni.showLoading({
      title: '请选择节点',
      mask: true
    })
    return
  };
  console.log('copyNode', copyNode)
  if(copyNode.getType() === 'img') {
    await ImageNode.createImageData(copyNode._imageNode.base64)
        .then((img) => {
          const copyImageNode = copyNode._imageNode.copy();
          copyImageNode.replaceImageData(img)
          copyNode.replaceImage(copyImageNode)
        })
        .catch(error => {
          console.error('Failed to load image:', error);
        })
  }
  // 左下偏移20
  copyNode?.shapeReact?.useMove(20, 20);
  copyNode?.drawCache();
  placard.addNode(copyNode)
  placard.canvasEvent.setSelectNode(copyNode)
  placard.renderDraw()
}

const text = ref('测试文字\n12345678910\n1234s试试')
const bindChangeText = async () => {
  const selectNodeBox = placard.canvasEvent.getSelectNode();
  console.log('bindChangeText',text.value, selectNodeBox,)
  if (selectNodeBox?.getType() === 'text') {
    selectNodeBox.updateAttribute('text', text.value);
    await selectNodeBox.drawCache();
  }
  placard.renderDraw()
}
const bindText = () => {
  if(!text.value) return
  const selectNodeBox = placard.canvasEvent.getSelectNode();
  console.log('selectNodeBox', selectNodeBox)
  if (selectNodeBox?.getType() === 'text') {
    selectNodeBox.updateAttribute('text', text.value);
    selectNodeBox.drawCache();
  }else {
    const textNode = new TextNode({
      text: text.value,
      fontSize: 20,
      color: 'red',
    })
    const textNodeBox = new TextNodeBox(textNode, placard!.getRenderReact())
    textNodeBox.setLocation('center')
    textNodeBox.drawCache()
    placard.addNode(textNodeBox)
    text.value = '';
  }
  placard.renderDraw()
}

const updateText = (key: string, value: string) => {
  const selectNodeBox = placard.canvasEvent.getSelectNode();
  if (!selectNodeBox) return;
  if(['horizontal', 'vertical'].includes(key)) {
    selectNodeBox.changeDirection(value); // 这应该可以工作了
  }else if(['lineWidth'].includes(key)) {
    const newValue = selectNodeBox.getAttribute(key) === value ? '' : value;
    selectNodeBox.updateAttribute(key, newValue);
  }else if(['fontWeight'].includes(key)) {
    const newValue = selectNodeBox.getAttribute(key) === value ? '' : value;
    selectNodeBox.updateAttribute(key, newValue);
  }else if(['fillStyle'].includes(key)) {
    const newValue = selectNodeBox.getAttribute(key) === value ? '' : value;
    selectNodeBox.updateAttribute(key, newValue);
  }else if (['underline'].includes(key)) {
    const textDecorationValues = ['underline', 'line-through', 'overline', ''].sort((a, b) => Math.random() - 0.5);
    updateTextAttribute('textDecoration', textDecorationValues[0]);
    updateTextAttribute('textDecorationColor', `#${Math.floor(Math.random()*16777215).toString(16).padStart(6, '0')}`);
  }
  selectNodeBox.drawCache();
  placard.renderDraw()
}


const changeHistory = (type: 'pre' | 'next') => {
  let historyItem;
  if(type ==='pre') {
     historyItem = placard.historyTask.undo()
  }else {
    historyItem = placard.historyTask.redo()
  }
  if(historyItem) {
    placard.resetNodeList(historyItem.historyNodeBoxList)
    placard.renderDraw(false)
  }
}


const images = shallowRef<[string]>([])
setInterval(async () => {
  const nodes = placard.getNodeList();
  const imagList: Array<string> = [];
  for (const node of nodes) {
    console.log('node', node)
    const img = await node.exportCanvasDataImg();
    imagList.push(img)
  }
  images.value = imagList
},2000)

const bindPreview = () => {
  uni.previewImage({
    urls: images.value,
  })
}

</script>

<style lang="scss" >
.content {
  align-items: center;
  justify-content: center;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
}
</style>
